Exoplanet Engine
An analysis engine for exoplanet transit detection and ML-assisted classification. Combines transit physics, time-series analysis, feature extraction, and sequence model classification into a single pipeline - from raw light curve to transit prediction.
Namespace: CSharpNumerics.Engines.Exoplanet
🔄 Pipeline Overview
LightCurve -> Preprocess -> BLS Period Search -> Transit Fit -> Validate -> Feature Extract -> ML Classify
The engine builds on existing library capabilities:
| Step | Uses |
|---|---|
| Preprocessing | TimeSeriesDetrending, LightCurveSanitizer |
| Period search | BoxFittingLeastSquares, LombScarglePeriodogram |
| Transit model | Physics.Astro.TransitModel, LimbDarkening, TransitGeometry |
| Fitting | NonlinearLeastSquaresFitter, GoodnessOfFit |
| Feature extraction | TransitFeatureExtractor, WindowedFeatureExtractor |
| ML classification | CNN1DClassifier, LSTMClassifier, BiLSTMClassifier via SupervisedExperiment |
| Statistics | SigmaClipping, SlidingWindowStatistics, FalseAlarmProbability |
| Engine infra | ISimulationEngine, EventBus from Engines.Common |
📦 Data Model
Light curves use a format compatible with Kepler/TESS FITS columns:
using CSharpNumerics.Engines.Exoplanet.Data;
// Create from arrays
var lc = new LightCurve(time, flux, fluxError, qualityFlags,
new LightCurveMetadata
{
TargetId = "TIC-12345678",
Mission = "TESS",
TimeOffset = 2457000.0,
Cadence = CadenceType.Short
});
// Or from a TimeSeries
var lc2 = LightCurve.FromTimeSeries(ts, "TIME", "PDCSAP_FLUX", "PDCSAP_FLUX_ERR");
// Sanitize
var clean = LightCurveSanitizer.RemoveBadQuality(lc, qualityMask: 0);
clean = LightCurveSanitizer.RemoveOutliers(clean, sigmaThreshold: 5.0);
clean = LightCurveSanitizer.NormalizeFlux(clean);
🔎 Classical Detection
Detect transit candidates without ML - uses BLS period search, transit model fitting, and validation:
using CSharpNumerics.Engines.Exoplanet.Pipeline;
var config = new TransitDetectionConfig
{
MinPeriodDays = 0.5,
MaxPeriodDays = 100.0,
SnrThreshold = 7.0,
MinTransitDepthPpm = 100,
MaxPlanets = 3,
DetrendingMethod = DetrendingMethod.MedianFilter,
PeriodSearchMethod = PeriodSearchMethod.BLS
};
TransitCandidate[] candidates = TransitDetectionPipeline.Detect(lc, config);
foreach (var c in candidates)
{
Console.WriteLine($"Period: {c.Parameters.Period:F4} d");
Console.WriteLine($"Depth: {c.Parameters.Depth * 1e6:F0} ppm");
Console.WriteLine($"Score: {c.Score:F3}");
}
🧬 Feature Extraction
Extract transit-specific features for ML classification:
using CSharpNumerics.Engines.Exoplanet.Features;
// Per-candidate features
TransitFeatureSet features = TransitFeatureExtractor.Extract(candidate, lc);
double blsSnr = features["SnrBls"];
double vShape = features["VShapeMetric"];
// Windowed training data (phase-folded + feature columns)
var (X, y) = WindowedFeatureExtractor.CreateTrainingData(
curves, candidates, labels, windowSize: 50);
Features extracted: Depth, Duration, Period, SnrBls, OddEvenRatio, VShapeMetric, SecondaryDepth, ScatterInTransit, ScatterOutTransit, LimbDarkeningU1, LimbDarkeningU2, IngressEgressRatio.
🤖 ML Training & Inference
Train a sequence classifier (CNN1D / LSTM / BiLSTM) on labeled transit data:
using CSharpNumerics.Engines.Exoplanet.Pipeline;
using CSharpNumerics.ML.Experiment;
var trainerConfig = new TrainerConfig
{
WindowSize = 50,
CandidateModels = new[] { TransitModelType.CNN1D, TransitModelType.LSTM },
Epochs = 150,
LearningRate = 0.02,
Filters = 8,
KernelSize = 5,
HiddenUnits = 8,
Cv = CrossValidatorConfig.KFold(folds: 3)
};
// Train with grid search + cross-validation
TrainedTransitModel model = TransitClassifierTrainer.Train(
curves, labels, trainerConfig, detectionConfig);
Console.WriteLine($"Best model: {model.ModelName}");
Console.WriteLine($"Accuracy: {model.Metrics.Accuracy:P1}");
Console.WriteLine($"F1 Score: {model.Metrics.F1Score:F3}");
// Serialize for deployment
byte[] bytes = ModelSerializer.Serialize(model);
ModelSerializer.SaveToFile(model, "transit_model.bin");
// Load and predict
var restored = ModelSerializer.LoadFromFile("transit_model.bin", model);
TransitPrediction[] predictions = restored.Predict(newLightCurve);
⚙️ Engine Integration
ExoplanetEngine implements ISimulationEngine for batch processing with event-driven notifications:
using CSharpNumerics.Engines.Exoplanet;
var engineConfig = new ExoplanetEngineConfig
{
Detection = new TransitDetectionConfig
{
MinPeriodDays = 0.5,
MaxPeriodDays = 50.0,
SnrThreshold = 7.0
}
};
var engine = new ExoplanetEngine(engineConfig);
// Subscribe to detection events
engine.Bus.Subscribe<TransitDetectedEvent>(evt =>
{
Console.WriteLine($"[t={evt.Timestamp:F1}s] Transit found: " +
$"P={evt.Candidate.Parameters.Period:F3} d, " +
$"depth={evt.Candidate.Parameters.Depth * 1e6:F0} ppm");
});
// Classical detection (no ML)
engine.Init();
// Or with a pre-trained model for ML-assisted classification:
// engine.Init(trainedModel);
// Process light curves
engine.Enqueue(lightCurve1);
engine.Enqueue(lightCurve2);
engine.Step(dt: 1.0);
Console.WriteLine($"Processed: {engine.ProcessedCount}");
Console.WriteLine($"Detections: {engine.Detections.Count}");